package gestion.camping.controleur;

import gestion.camping.connexion.Connexion;
import gestion.camping.dao.impl.FraisReservationDao;
import gestion.camping.dao.impl.ReservationDao;
import gestion.camping.dao.impl.StatutReservationDao;
import gestion.camping.dao.impl.TypeLocationDao;
import gestion.camping.dto.Reservation;
import gestion.camping.dto.ReservationPdf;
import gestion.camping.dto.StatutReservation;
import gestion.camping.dto.TypeLocation;
import gestion.camping.utils.DateFormatUtils;
import gestion.camping.utils.MessagesUtil;
import gestion.camping.vue.ViewErreur;
import gestion.camping.vue.ViewReservationDetail;
import gestion.camping.vue.ViewReservationListe;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.JDialog;
import javax.swing.JPanel;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.view.JasperViewer;

public class ReservationController{
	
	private Reservation reservation;
	private List<Reservation> listReservation;
	private List<TypeLocation> listTypeLocation;
	private List<StatutReservation> listStatutReservation;
	private StatutReservation statutReservation;
	private ReservationDao reservationDao = new ReservationDao(Connexion.getInstance());
	private TypeLocationDao typeLocationDao = new TypeLocationDao(Connexion.getInstance());
	private FraisReservationDao fraisReservationDao = new FraisReservationDao(Connexion.getInstance());
	private StatutReservationDao statutReservationDao = new StatutReservationDao(Connexion.getInstance());
	private ViewReservationDetail frameDetail;
	private ViewReservationListe frameListe;
	private Date dateDebut;
	private Date dateFin;
	private Integer id;
	
	/**
	 * Constructeur du controlleur reservation
	 */
	public ReservationController(){
		//On récupère la liste des type de location
		listTypeLocation = typeLocationDao.findAllTypeLocation();		
		
		listStatutReservation = statutReservationDao.findAllStatut();
	}

	/**
	 * Accesseur à l'attribut reservation
	 * @return personne
	 */
	public Reservation getReservation() {
		return reservation;
	}

	/**
	 * Permet la modification de l'attribut reservation de l'instance courante
	 * @param reservation
	 */
	public void setReservation(Reservation reservation) {
		this.reservation = reservation;
	}
	
	/**
	 * Accesseur aux JPanel contenant la liste des personnes
	 * @return JPanel viewListe
	 */
	public JPanel getViewListe(){
		
		if(listReservation == null){
			listReservation = new ArrayList<Reservation>();
		}
		
		
		//On crée la fenêtre
		frameListe = new ViewReservationListe(this);
	
		rechercher(null, null, null, null);
		
		return frameListe;
	}
	
	/**
	 * Accesseur aux JPanel contenant le détail d'une personne
	 * @return JPanel viewDetail
	 */
	public JDialog getViewDetail(){
		
		// Si personne est différent de null 
		if(reservation == null){
			//on est en création
			//On crée un objet vide
			reservation = new Reservation();
		}
				
		//On crée la fenêtre
		frameDetail = new ViewReservationDetail(this);
		
		frameDetail.setVisible(true);
		
		return frameDetail;
	}

	/**
	 * Accesseur à la liste des personnes
	 * @return Liste des personnes
	 */
	public List<Reservation> getListReservation() {
		return listReservation;
	}

	/**
	 * Permet la modification de la liste de personne
	 * @param listPersonne
	 */
	public void setListReservation(List<Reservation> listReservation) {
		this.listReservation = listReservation;
	}
	
	public void ajouterOccupant(Reservation reservation2) {   
	}	

	/**
	 * Permet la gestion de l'action utilisateur Enregistrer
	 * @param personne
	 */
	public void enregistrer(Reservation reservation, double arrhe, double fraisResa) {
		System.out.println(reservation.toString());
		
		//Si l'ID est zéro
		if(reservation.getStatut().getId() == 0){ 
			//On est en création
			reservation = reservationDao.create(reservation, arrhe, fraisResa);
		}else if(reservation.getStatut().getId() == 1){
			//On confirme la réservation car le dossier est incomplet
			reservation = reservationDao.confirmation(reservation, arrhe, fraisResa);
		}
		
		if(reservation.getStatut().getId() == 2){
			afficherConfirmation();
		}
		
		frameDetail.setReservation(reservation);
	}

	private void afficherConfirmation() {
		 
			String source = "./pdf/confirmation.jasper"; 
	      
	      
	      ReservationPdf reservationPdf = new ReservationPdf(reservation);
	      reservationPdf.setListOccupant(reservationDao.findOccupant(reservation));
	      reservationPdf.setListVisiteur(reservationDao.findVisiteur(reservation));
	      reservationPdf.setMontantTotalSejour(reservationDao.calculTotal(reservation));
	      reservationPdf.setMontantFraisResa(fraisReservationDao.find(Integer.valueOf(DateFormatUtils.formatDate(reservationPdf.getDateDebut()).substring(6))).getPrix());
	      
	      List<ReservationPdf> listReservation = new ArrayList<ReservationPdf>();
	      listReservation.add(reservationPdf);
	      
		try {
			JasperReport jasperReport;
			jasperReport = (JasperReport) JRLoader.loadObject(new File(source));
			
			JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null, new JRBeanCollectionDataSource(listReservation));
			
	        JasperViewer.viewReport(jasperPrint, false);
	        
		} catch (JRException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		
	}

	/**
	 * Permet la gestion de l'action utilisateur Rechercher
	 */
	public void rechercher(StatutReservation statut, Date dateDeb, Date dateFin, Integer numeroResa) {
		
		if(statut == null && dateDeb == null && dateFin == null && numeroResa == null ){
			this.statutReservation = null;
			this.dateDebut= null;
			this.dateFin=null;
			this.id=null;
			
			//On alimente la liste des personnes
			this.listReservation = reservationDao.findAllReservation();
		}else{
			this.listReservation = reservationDao.findByStatutDateId(statut, dateDeb, dateFin, numeroResa);
			
			this.statutReservation = statut;
			this.dateDebut = dateDeb;
			this.dateFin = dateFin;
			this.id = numeroResa;
		}
		
		//On met à jour la fenêtre
		frameListe.setListReservation(listReservation);
	}

	/**
	 * Permet la gestion de l'action utilisateur Modifier
	 * @param personne
	 */
	public void modifier(Reservation reservation) {
		//On affecte la personne que l'on veut modifier	
		this.reservation = reservation;
		
		//On affiche la fenêtre de détail
		this.getViewDetail();
	}
	
	/**
	 * Permet la gestion de l'action utilisateur Ajouter
	 * @param personne
	 */
	public void ajouter() {
		this.reservation = new Reservation();
		
		this.getViewDetail();
		
	}

	/**
	 * Permet la gestion de l'action utilisateur Retour à liste 
	 */
	public void retour() {
		//On retourne à la liste des personnes
		HomeController.setPanelFrame(this.getViewListe());
		
		//On effectue la dernière recherche
		rechercher(statutReservation, dateDebut, dateFin, id);
	}

	public List<TypeLocation> getListTypeLocation() {
		return listTypeLocation;
	}

	public void setListTypeLocation(List<TypeLocation> listTypeLocation) {
		this.listTypeLocation = listTypeLocation;
	}

	public void calculer(Reservation reservation) {
		reservation.setMontant(reservationDao.calculTotal(reservation));
		frameDetail.setReservation(reservation);
	}

	public void testDisponibilite(Reservation reservation) {
		ViewErreur frame;
		if(reservationDao.testDisponibilite(reservation)){
			frame = new ViewErreur(MessagesUtil.formatMessage("reservation.detail.message.test.ok"));
			
		}else{
			frame = new ViewErreur(MessagesUtil.formatMessage("reservation.detail.message.test.nok"));
		}
		
		frame.setVisible(true);
	}

	public void attributionCarte(Reservation reservation) {
		this.reservation  = reservationDao.attributionCarte(reservation);
		
		frameDetail.setReservation(this.reservation);
	}

	public void editionFacture(Reservation reservation) {
		  try {

		      String source = "./pdf/facture.jasper"; 
		      
		      ReservationPdf reservationPdf = new ReservationPdf(reservation);
		      reservationPdf.setListOccupant(reservationDao.findOccupant(reservation));
		      reservationPdf.setListVisiteur(reservationDao.findVisiteur(reservation));
		      reservationPdf.setMontantTotalSejour(reservationDao.calculTotal(reservation));
		      reservationPdf.setMontantFraisResa(fraisReservationDao.find(Integer.valueOf(DateFormatUtils.formatDate(reservationPdf.getDateDebut()).substring(6))).getPrix());
		      
		      List<ReservationPdf> listReservation = new ArrayList<ReservationPdf>();
		      listReservation.add(reservationPdf);
		      		       
		      
		      JasperReport jasperReport = (JasperReport) JRLoader.loadObject(new File(source)); 
		      JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null, new JRBeanCollectionDataSource(listReservation));

		      JasperViewer.viewReport(jasperPrint, false);

	        } catch (Exception e) { 
	            e.printStackTrace(); 
	            System.out.println("reports Error  " + e.toString());

	        }
		
	}

	public void setListStatutReservation(List<StatutReservation> listStatutReservation) {
		this.listStatutReservation = listStatutReservation;
	}

	public List<StatutReservation> getListStatutReservation() {
		return listStatutReservation;
	}

	public void setStatutReservation(StatutReservation statutReservation) {
		this.statutReservation = statutReservation;
	}

	public StatutReservation getStatutReservation() {
		return statutReservation;
	}

	public void restitutionCarte(Reservation reservation) {
		this.reservation = reservationDao.restitutionCarte(reservation);
		
		frameDetail.setReservation(this.reservation);
		
		ViewErreur frame = new ViewErreur(MessagesUtil.formatMessage("erreur.reservation.archiver"));	
		frame.setVisible(true);
	}
}
